﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Game
{
   // 游戏核心逻辑
   class Core
   {
      // 地图大小
      public static int ROW = 4;
      public static int COL = 3;
      // GOAL坐标
      private static int GOAL_LOC_X = ROW - 1;
      private static int GOAL_LOC_Y = COL / 2;
      // 棋盘
      public char[,] map = new char[ROW, COL];
      // 游戏对象集合
      public List<IGameObject> objects = new List<IGameObject>();
      // 关卡配置单
      private List<IGameObject[]> levelList = new List<IGameObject[]>();

      // 初始化
      public Core()
      {
         // 初始化棋盘
         InitMap();

         // 设置最后一行的内容（目标点）
         for (int i = 0; i < GOAL_LOC_Y; i++)
            AddGameObject(new FixedObject(ROW - 1, i));
         AddGameObject(new FixedObject(GOAL_LOC_X, GOAL_LOC_Y, true));
         for (int i = GOAL_LOC_Y + 1; i < COL; i++)
            AddGameObject(new FixedObject(ROW - 1, i));

         // 设置关卡配置单
         // 关卡1
         levelList.Add(new IGameObject[1] {
            new MovableObject(0, 1, true) });
         // 关卡2
         levelList.Add(new IGameObject[3] {
            new MovableObject(0, 1, true), 
            new MovableObject(1, 1),
            new FixedObject(0, 0)
         });
         // 关卡3
         levelList.Add(new IGameObject[3] {
            new MovableObject(0, 2, true),
            new MovableObject(1, 0),
            new MovableObject(1, 2)
         });
         // 关卡4
         levelList.Add(new IGameObject[3] {
            new MovableObject(0, 1, true),
            new MovableObject(0, 2),
            new FixedObject(1, 1)
         });
         // 关卡5
         levelList.Add(new IGameObject[5] {
            new FixedObject(0, 1),
            new MovableObject(1, 1),
            new FixedObject(2, 0),
            new MovableObject(2, 1),
            new MovableObject(2, 2, true)
         });
      }

      // 开始游戏
      public void Start()
      {
         // 开始菜单用户输入
         string startIpt = null;
         // 游戏过程中用户输入
         string gameIpt = null;
         // 打印开始菜单
         PrintStartUI();

         // 开始菜单交互
         do
         {
            startIpt = Console.ReadLine();
            switch (startIpt)
            {
               case "1":   // 游戏开始
                  goto GameStart;
               case "0":   // 退出游戏
                  goto GameEnd;
               default:    // 错误输入
                  Console.WriteLine("输入错误，请重新输入");
                  break;
            }
         } while (true);

      GameStart:  // 游戏开始
         {
            for (int i = 0; i < levelList.Count; i++)
            {
               // 加载关卡
               LoadLevel(levelList[i]);

               // 游戏内用户交互
               do
               {
                  // 交互UI
                  PrintGameUI(i);
                  Console.WriteLine("[1] ↑  [2] →  [3]↓  [4]←  [5]重新开始  [0]退出游戏");
                  gameIpt = Console.ReadLine();

                  // 获取可移动的对象
                  List<MovableObject> movableList = new List<MovableObject>();
                  foreach (var item in objects)
                  {
                     if (item is MovableObject)
                        movableList.Add((MovableObject)item);
                  }

                  // 移动
                  switch (gameIpt)
                  {
                     case "1": // ↑
                        for (int j = 0; j < movableList.Count; j++)
                        {
                           movableList[j].MoveUp(objects);
                        }
                        break;
                     case "2": // →
                        for (int j = movableList.Count - 1; j >= 0; j--)
                        {
                           movableList[j].MoveRight(objects);
                        }
                        break;
                     case "3": // ↓
                        for (int j = movableList.Count - 1; j >= 0; j--)
                        {
                           movableList[j].MoveDown(objects);
                        }
                        break;
                     case "4": // ←
                        for (int j = 0; j < movableList.Count; j++)
                        {
                           movableList[j].MoveLeft(objects);
                        }
                        break;
                     case "5": // 重置
                        InitMap();  // 初始化地图
                        ClearObjects();   // 清空表中可变元素
                        //RefreshMap();  // 刷新地图
                        LoadLevel(levelList[i]);   // 重新加载关卡
                        break;
                     case "0": // 退出
                        goto GameEnd;
                     default:
                        break;
                  }

                  // 刷新地图
                  RefreshMap();

                  // 判断结果
                  if (IsSucceed())
                  {
                     ClearObjects();
                     RefreshMap();
                     break;
                  }
               } while (true);
            }
            PrintSucceedUI();
            Console.ReadLine();
         }

      GameEnd: // 游戏结束
         {
            Console.Clear();
            Console.WriteLine("*******************");
            Console.WriteLine("     GOODBYE!");
            Console.WriteLine("*******************");
         }
      }

      // 初始化棋盘
      private void InitMap()
      {
         for (int i = 0; i < ROW; i++)
         {
            for (int j = 0; j < COL; j++)
            {
               map[i, j] = ' ';
            }
         }
      }

      // 打印进入界面
      private void PrintStartUI()
      {
         Console.WriteLine(" ===================");
         Console.WriteLine("    星   之   巡");
         Console.WriteLine(" ===================");
         Console.WriteLine("    [1] 开始游戏");
         Console.WriteLine("    [0] 退出游戏");
      }

      // 打印游戏界面
      private void PrintGameUI(int i)
      {
         Console.Clear();
         Console.WriteLine($"  第{i + 1}关");
         Console.WriteLine("==========");
         PrintMap();
         Console.WriteLine("==========");
      }

      // 打印作者信息
      private void PrintAuthorInfo()
      {
         Console.WriteLine();
         Console.WriteLine("************************************");
         Console.WriteLine("*******      作者 itmWuma    *******");
         Console.WriteLine("****   邮箱 2913850205@qq.com   ****");
         Console.WriteLine("************************************");
      }

      // 打印通关界面
      private void PrintSucceedUI()
      {
         Console.Clear();
         Console.WriteLine("==========");
         RefreshMap();
         PrintMap();
         Console.WriteLine("==========");
         Console.WriteLine("恭喜，您已通关！");
         PrintAuthorInfo();
      }

      // 打印棋盘
      private void PrintMap()
      {
         for (int i = 0; i < ROW; i++)
         {
            for (int j = 0; j < COL; j++)
            {
               Console.Write($" {map[i, j]} ");
            }
            Console.WriteLine();
         }
      }

      // 添加游戏对象
      private void AddGameObject(IGameObject gameObject)
      {
         objects.Add(gameObject);
         map[gameObject.X, gameObject.Y] = gameObject.Name;
      }

      // 加载关卡
      private void LoadLevel(params IGameObject[] gameObjects)
      {
         foreach (var item in gameObjects)
         {
            if (item is MovableObject)
               objects.Add(new MovableObject(item.X, item.Y, ((MovableObject)item).IsStar));
            else
               objects.Add(new FixedObject(item.X, item.Y, ((FixedObject)item).IsGoal));
            map[item.X, item.Y] = item.Name;
         }
      }

      // 清空游戏对象列表
      private void ClearObjects()
      {
         objects.RemoveRange(COL, objects.Count - COL);
      }

      // 刷新地图
      private void RefreshMap()
      {
         InitMap();
         foreach (var item in objects)
         {
            map[item.X, item.Y] = item.Name;
         }
      }

      // 判断是否成功
      private bool IsSucceed()
      {
         return map[GOAL_LOC_X - 1, GOAL_LOC_Y] == '*';
      }
   }
}
